package com.hqq.rabbitmq.publisher;

import com.hqq.rabbitmq.entity.Person;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

/**
 * 对象类型消息发送者
 * @author huangqiqin
 * @date 2021/04/16 22:32
 **/
@Component
public class ObjectMessagePublisher {

    /**
     * 注入配置文件变量对象
     */
    @Autowired
    private Environment env;

    /**
     * 注入Rabbit模板
     */
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送对象消息
     * @param person
     */
    public void sendObjectMessage(Person person){
        try {
            if (person != null){
                // 设置消息传输格式（Json）
                this.rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                // 指定发送消息到对应的交换机
                this.rabbitTemplate.setExchange(env.getProperty("mq.object.exchange.name"));
                // 指定发送消息时对应的路由key
                this.rabbitTemplate.setRoutingKey(env.getProperty("mq.object.routing.key.name"));

                // 转换格式并发送消息，并重写消息发送后置处理器
                this.rabbitTemplate.convertAndSend(person, new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        // 获取消息属性
                        MessageProperties messageProperties = message.getMessageProperties();
                        // 设置消息持久化模式
                        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                        // 设置消息类型（这里需要指定消息类型为Person类型，否则消费者无法直接接收Person对象消息）
                        messageProperties.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME,
                                Person.class
                        );
                        return message;
                    }
                });
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

}
